package server.app.fileupload;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import annotation.Inject;
import annotation.Service;
import common.BaseUtils;
import common.html.DefaultTag;
import common.html.HtmlWriter;
import common.html.Tag.PageTag;
import common.html.Tag.Text;
import common.html.TagFactory;
@Service(name = "upload2", applaction = "/upload2")
public class FileUploadHandler extends AbstractHandler implements Resource
{
    ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(50);
    static LinkedList<String> imgNameList = new LinkedList<String>();
    File imageRootDirectory;
    DiskFileItemFactory factory;
 
    
    public FileUploadHandler()
    {
        super();
    }

    public FileUploadHandler(File imagesDirectory)
    {
        this();
        init(imagesDirectory);
    }

    @Inject(name = "FileUploadHandler.file", param = "app.fileupload.root2", type = File.class)
    public void setDirecory(File directory)
    {
        init(directory);
    }

    private void init(File imagesDirectory)
    {
        imageRootDirectory = imagesDirectory;
        factory = new DiskFileItemFactory();
        factory.setRepository(imageRootDirectory);
        scheduledService.scheduleAtFixedRate(new ImgCompress(imageRootDirectory, this), 5, 30, TimeUnit.SECONDS);
    }

    static void addImage(String imgPath)
    {
        imgNameList.addLast(imgPath);
    }

    public void handle(String target,
                    Request baseRequest,
                    HttpServletRequest request,
                    HttpServletResponse response)
                    throws IOException, ServletException
    {
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        baseRequest.setHandled(true);
        HtmlWriter hw = new HtmlWriter(response.getWriter());
        PageTag pt = new PageTag();

        pt.addHeaderElement(TagFactory.createLink("res/css/bootstrap.css"),
            TagFactory.createScript("res/js/jquery-2.0.3.js"));

        pt.addBodayElement(
            TagFactory.createTag("h1", "Hello World"),
            TagFactory.createTag("hr")
                        );
        // hw.h1("Hello World");
        // hw.hr();
        if (HttpMethods.GET.equalsIgnoreCase(request.getMethod()))
        {
            writeGet(pt);
        }
        else if (HttpMethods.POST.equalsIgnoreCase(request.getMethod()))
        {
            // hw.h1("POST File... ");
            // case 1 a simple upload case.
            outputFile(request, pt);

            // hw.h1("POST File Success ");

            writeGet(pt);
        }

        pt.write(hw);
    }

    private void outputFile(HttpServletRequest request, PageTag pt)
    {
        ServletFileUpload upload = getFileUpload();

        // Parse the request
        List<FileItem> items = null;
        try
        {
            items = upload.parseRequest(request);
        }
        catch (FileUploadException e1)
        {
            e1.printStackTrace();
        }
        for (FileItem fileItem : items)
        {
            if (!fileItem.isFormField())
            {
                String fileName = fileItem.getName();
                boolean isInMemory = fileItem.isInMemory();
                String storeFileName =
                                BaseUtils.getUUIDAndFileNameByBase64(StringUtils.substringBefore(fileName, "."));
                storeFileName = storeFileName + "." + StringUtils.substringAfter(fileName, ".");
                if (!isInMemory)
                {
                    File uploadedFile = new File(imageRootDirectory, storeFileName);
                    try
                    {
                        fileItem.write(uploadedFile);
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                    DefaultTag print = TagFactory.createTag("p");
                    Text pText = new Text("File %s already upload,plase link this to view ", fileName);
                    DefaultTag a =
                                    TagFactory.createTag("a", "Click me!",
                                        new String[][] { { "href", String.format("res/img/%s", storeFileName) } });

                    print.content(pText, a);
                    pt.addBodayElement(print);

                    DefaultTag smallTag =
                                    TagFactory.createTag("img",
                                        new String[][] { { "src", String.format("res/img/%s", storeFileName) },
                                                        { "height", "250px" }, { "width", "250px" } });
                    smallTag.putclass("img-rounded");
                    pt.addBodayElement(smallTag);

                    addImage(storeFileName);
                }
                else
                {
                    // InputStream uploadedStream = fileItem.getInputStream();
                    // uploadedStream.close();
                }
            }
        }
    }

    private ServletFileUpload getFileUpload()
    {
        return new ServletFileUpload(factory);
    }

    private void writeGet(PageTag page)
    {
        DefaultTag fromTag =
                        TagFactory.createTag("form", new String[][] { { "action", "/upload2/" }, { "method", "POST" },
                                        { "enctype", "multipart/form-data" } });
        /*
         * <div class="form-group"> <label for="exampleInputFile">File input</label> <input
         * type="file" id="exampleInputFile"> <p class="help-block">Example block-level help text
         * here.</p> </div>
         */
        DefaultTag divTag = TagFactory.createTag("div");
        divTag.putclass("form-group");

        DefaultTag labelTag = TagFactory.createTag("label", "File Input", new String[][] { { "for", "selectorFile" } });
        DefaultTag helpTag = TagFactory.createTag("p", "Upload your image!!!");
        helpTag.putclass("help-block");
        DefaultTag inputTag =
                        TagFactory.createTag("input",
                            new String[][] { { "id", "selectorFile" }, { "type", "file" }, { "name", "fileUpload" } });
        DefaultTag buttonTag =
                        TagFactory.createTag("button ", new String[][] { { "type", "submit" } });
        buttonTag.content("Upload");
        buttonTag.putclass("btn btn-primary");

        divTag.content(labelTag, inputTag, helpTag, buttonTag);

        fromTag.content(divTag);

        // BodyTag bt = new BodyTag();
        // bt.content(fromTag);
        // bt.write(hw);
        // fromTag.write(hw);
        page.addBodayElement(fromTag);
    }

    public synchronized LinkedList<String> getResource()
    {
        return imgNameList;
    }

    public LinkedList<String> addResource(String resource)
    {
        addImage(resource);
        return getResource();
    }
}
